#include<iostream>
#include "../PID.h"
#include "Gnuplot2Show.h"

using namespace std;

/*****************************************************
 * 创建一个系统--加热水到指定温度80°，并保持不上升也不下降
 * ***************************************************/
class Water
{
    public:
        float initTemper = 0;   //存储环境温度
        float temper = 0;       //存储水温度
        float cool = 1;         //储存单位时间水冷却的度数（应该用比热容计算才合理，此处简化）
        float heatMax = 20;     //储存单位时间水加热的度数（应该用比热容计算才合理，此处简化）

        //设置温度
        void setTemper(float t, float initT, float heatM=10, float c=1){        
            temper = t;
            cool = c;
            initTemper = initT;
            heatMax = heatM;
        }

        //返回温度，模拟温度监控
        float getTemper(){
            return temper;
        }

        //降温函数，模拟水正常情况下温度会下降
        //参数 k 用于自动调整冷却速率
        void coolDown(float k=1){ 
            if(temper>=initTemper)    //当水温度高于环境温度才存在降温现象
                temper -= cool*k;
        }

        //用于加热水
        //t 为单位时间加热温度
        void heat(double t){
            if(t>=0){   //系统只提供加热不提供冷却操作
                if(t>=heatMax) temper += heatMax;  //系统有功率限制，单位时间内最高加热
                else temper += t;  
            } 
            
        }
};


int main(){
    Pid p;                          //初始化Pid类
    Water w;                        //初始化Water类
    float cool = 2;                 
    float Ex = 80;

    w.setTemper(20, 20, 10, 1);       //设置环境温度，水初始温度，降温速率
    p.setPid(3.5, 0.04, 1, 0.1);       //设置pid参数
    p.setEx(Ex);                    //设置期望
    
    int num = 200;                  //数据点
    double t_y[num];                //用于记录温度作为 y
    double x[num];                  //用于记录数据 x（时间相关）

    int i = 0;
    while(i < num){
        float t = w.getTemper();    //获取温度（反馈）
        t_y[i] = t;                 //记录温度
        x[i] = i;                   //记录 x（时间相关）
        double heat = p.clac(t);    //pid计算，返回调整值
        w.heat(heat);               //调整值加热
        w.coolDown();               //单位时间能量流失处理（温度下降）
        i++;
    }

    Gnuplot2Show(x, t_y, num, Ex);  //数据写入文件 并可视化处理

    return 0;
}